package pl.edu.mimuw.irs.core.model.analysis.dd;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

import pl.edu.mimuw.irs.core.global.IDManager;
import pl.edu.mimuw.irs.core.model.analysis.ResourcePlace;
import pl.edu.mimuw.irs.core.model.analysis.TPair;
import pl.edu.mimuw.irs.core.model.design.IRSActivity;
import pl.edu.mimuw.irs.core.model.design.processing.Requirement;
import pl.edu.mimuw.irs.core.model.design.processing.Resource;
import pl.edu.mimuw.irs.core.model.petrinet.Transition;

public class DDFire extends Transition {
	
	private static final long serialVersionUID = -4238326841667844469L;
	
	// *** Attributes

	private ActivityWrapper activity;
	private DependenciesGraph graph;
	private Map<Resource, TPair> hiringMap;
	private LinkedHashMap<Requirement, Set<ResourcePlace>> requirementsResourcesMap;
	private Map<IRSActivity, Set<ResourcePlace>> hiredResources;
	public ActivityWrapper getActivity() {
		return activity;
	}
	public DependenciesGraph getGraph() {
		return graph;
	}
	public Map<Resource, TPair> getHiringMap() {
		if (hiringMap == null) hiringMap = 
			new LinkedHashMap<Resource, TPair>();
		return hiringMap;
	}
	public LinkedHashMap<Requirement, Set<ResourcePlace>> getRequirementsResourcesMap() {
		if (requirementsResourcesMap == null) requirementsResourcesMap = 
			new LinkedHashMap<Requirement, Set<ResourcePlace>>();
		return requirementsResourcesMap;
	}
	public Map<IRSActivity, Set<ResourcePlace>> getHiredResources() {
		if (hiredResources == null) hiredResources = 
			new LinkedHashMap<IRSActivity, Set<ResourcePlace>>();
		return hiredResources;
	}
	
	// *** Constructors
	
	public DDFire(IDManager idManager, ActivityWrapper activity, DependenciesGraph graph,
			Map<Resource, TPair> hiringMap, 
			LinkedHashMap<Requirement, Set<ResourcePlace>> requirementsResourcesMap, 
			Map<IRSActivity, Set<ResourcePlace>> map) {
		super(idManager, idManager.getPrefixedNewId("Fire" + activity.getActivity().getId()), 
				activity.getActivity().getPosition().left().under());
		this.activity = activity;
		this.graph = graph;
		this.hiringMap = hiringMap;
		this.requirementsResourcesMap = requirementsResourcesMap;
		this.hiredResources = map;
	}
	
	// *** Methods

	/*
	 * Reimplemented invoke of simple transition. 
	 */
	@Override
	public void invoke() {
		Map<IRSActivity, Set<ResourcePlace>> hiredMap = getHiredResources();
		Set<ResourcePlace> hired = hiredMap.get(getActivity().getActivity());
		hiredMap.remove(getActivity().getActivity());
		
		freeResources(hired);
		
		getGraph().end(getActivity());
		super.invoke();
	}
	
	private void freeResources(Set<ResourcePlace> hired) {
		for (ResourcePlace resourcePlace : hired) {
			TPair pair = getHiringMap().get(resourcePlace.getResource());
			pair.getFire().invoke();
		}
	}
	
	@Override
	public String toString() {
		return getId();
	}
}
